package de.koller.worlders.engine.entity.enc.pathfinding;

import de.koller.worlders.WorldersRoot;
import de.koller.worlders.engine.entity.plattform.Plattform;
import de.koller.worlders.engine.tiles.Tile;
import de.koller.worlders.engine.tiles.data.TileKey;
import java.util.Map;

public class TileNode implements Comparable<TileNode> {
	
	final Tile tile;
	final int tx, ty;
	TileNode predecessor = null; 
	
	float depth = 0;
	float f = 0;
	
	static TileNode create( WorldersRoot wroot, int tx, int ty, Map<String, TileNode> buffer ) {
		String k = TileKey.toKey( tx, ty );
		TileNode tn = buffer.get( k );
		if( tn != null )
			return tn;
		
		Tile t = wroot.getTileMap().getTileAt( tx, ty ).getTile();
		tn = new TileNode( t, tx, ty );
		buffer.put( k, tn );
		
		return tn;
	}
	
	private TileNode( Tile t, int tx, int ty ) {
		this.tx = tx;
		this.ty = ty;
		this.tile = t;
	}

	
	public boolean isBlocked( TileNode from, Map<String, TileNode> buffer ) {
		if( from.equals( this ) )
			return tile.getTileEntity() instanceof Plattform;
		
		int minX = Math.min( tx, from.tx );
		int minY = Math.min( ty, from.ty );
		int maxX = Math.max( tx, from.tx );
		int maxY = Math.max( ty, from.ty );
		
		for( int x = minX; x <= maxX; x++ )
			for( int y = minY; y <= maxY; y++ ) {
				TileNode tn = TileNode.create( tile.root, x, y, buffer );
				if( tn.equals( from ) )
					continue;
				
				if( tn.isBlocked( tn, buffer ) )
					return true;
			}
		
		return false;
	}
	
	public float getWeight( TileNode from ) {
		float dx = tx - from.tx;
		float dy = ty - from.ty;
		float result = (float)( Math.sqrt( (dx*dx) + (dy*dy) ) );
		return result;
	}

	@Override
	public int compareTo( TileNode o ) {
		return Float.compare( this.f, o.f );
	}
	
	@Override
	public boolean equals( Object obj ) {
		if( obj == null ) {
			return false;
		}
		if( getClass() != obj.getClass() ) {
			return false;
		}
		final TileNode other = ( TileNode ) obj;
		if( this.tx != other.tx ) {
			return false;
		}
		if( this.ty != other.ty ) {
			return false;
		}
		return true;
	}

	@Override
	public int hashCode() {
		int hash = 5;
		hash = 47 * hash + this.tx;
		hash = 47 * hash + this.ty;
		return hash;
	}
	
}
